-------------------------------------------------------------------------------
-- RTSAI - Real-Time Strategy engine for AI research
-- Copyright(C) 2006 DIMAp-UFRN, licensed under LGPL
--
-- RTSAI state machine example
-------------------------------------------------------------------------------

State {
    -- STATE ATTRIBUTES -------------------------------------------------------
    name = "seeking_the_flag",  -- obrigatory field (name)
    count = 10,       -- you can set any other attributes
    var_count = 0,

    -- STATE FUNCTIONS --------------------------------------------------------

    -- This function is called when a unit is getting to this state.
    -- It is useful for initializing some variables before entering in
    -- the game iteration (for instance, for setting up a planning process).
    on_enter = function ( self )
        --[
        print ("entering in the state: seeking")
        local numobjs = game:get_num_objs ( )
        print (numobjs)
        for i = 0, numobjs-1 do
            local obj = game:get_obj ( i );
            if obj:get_type() == "target1" then
                self.target = obj:position()
            end
        end
        --]]
    end,

    -- This function is called on each game loop iteration.
    -- It must return the action that the unit will perform on that iteration,
    -- otherwise the unit does nothing.

    act = function ( self )
        -- test if the unit reached the target
        local pos = self.unit:position()
        local dist = rtsai.Vector3D:distance ( pos, self.target )

        -- if reached, change state
        if dist < self.unit:radius() then
            -- self.unit:call_for_proposal ( "Contents" )
            --self.unit:change_state ( chasing:new() )
            action.change_state.state = chasing
            return action.change_state
        end

        -- otherwise, steer to target
        action.move.steer = self.unit:steerForSeek(self.target)
        return action.move
    end,

    -- This function is called before the unit changes to another state.
    -- It is useful, for instance, for getting back a variable to a previous
    -- or value for freeing pre-alocated resources.
    on_exit = function ( self )
        --print ("Leaving state <state>")
    end,

    -- EVENT CALLBACKS --------------------------------------------------------

    -- All event callback start with "on_" and it is followed by the name of
    -- the event the state is listening to. This means that the state is
    -- registered to listen an event named ABC if there exists a function
    -- named "on_ABC". When the event ABC happens, the function "on_ABC" is
    -- called.
    -- An event callback (e.g. "on_ABC") receives two parameters: the state
    -- itself (self) and the data generated by the event (event).
    -- If an event callback function returns a new state, then the current
    -- unit will change its state for the returning one. This is useful
    -- for mapping an event to a state transition.


    -- This is an example for reacting to the "random_event" event.
    -- It increments the state attribute "count" and changes the state of the
    -- unit if the random value generated be the event is smaller then 0.005
    on_sync_event = function ( self, event )
        return chasing:new()  -- a new state is set to the unit
    end,

    on_message = function ( self, messages )
        for i = 0, messages:size()-1 do
            local msg = messages[i]
            print ( msg:get_conversation_id() )
        end
    end
}

State {
    name = "chasing",  -- obrigatory field (name)

    on_enter = function ( self )
        -- "unit" is an implicity attribute of the state that can be used
        -- for accessing values or methods of the unit executing this state.
        -- The attributes of its class can also be consulted.
        -- In the example below, the attribute "max_life" of the unit is
        -- printed. Such an attribute is inherited from the unit class,
        -- which is "warrior" (see the civilization file set in the main
        -- game script).
        --[
        local numobjs = game:get_num_objs ( )
        for i = 0, numobjs-1 do
            local obj = game:get_obj ( i );
            if obj:get_type() == "target2" then
                self.target = obj:position()
            end
        end
        --]]
    end,

    -- in this state, the unit execute the "move" action.
    act = function ( self )
        -- test if the unit reatched the target
        local pos = self.unit:position()
        local dist = rtsai.Vector3D:distance ( pos, self.target )

        -- if reached, change state
        if dist < self.unit:radius() then
            action.change_state.state = seeking_the_flag
            return action.change_state
        end

        -- otherwise, steer to target
        action.move.steer = self.unit:steerForSeek(self.target)
        return action.move
    end,

    on_exit = function ( self )
        --print ("Leaving state <another>")
    end,

    on_sync_event = function ( self, event )
        -- as soon the event happen, the unit change its state
        -- print ("--------change--------")
        return seeking_the_flag:new()
    end
}
